package com.myBlog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.myBlog.domain.ResponseResult;
import com.myBlog.domain.dto.UserDTO;
import com.myBlog.domain.entity.Role;
import com.myBlog.domain.entity.User;
import com.myBlog.domain.entity.UserRole;
import com.myBlog.domain.vo.PageVo;
import com.myBlog.domain.vo.UserInfoVo;
import com.myBlog.domain.vo.UserRoleVo;
import com.myBlog.mapper.UserMapper;
import com.myBlog.service.RoleService;
import com.myBlog.service.UserRoleService;
import com.myBlog.service.UserService;
import com.myBlog.utils.BeanCopyUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserRoleService userRoleService;
    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private RoleService roleService;

    /**
     * 条件分页查询用户
     *
     * @param pageNum
     * @param pageSize
     * @param userDTO
     * @return
     */
    @Override
    public ResponseResult<PageVo> list(Integer pageNum, Integer pageSize, UserDTO userDTO) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(userDTO.getUserName()), User::getUserName, userDTO.getUserName());
        wrapper.like(StringUtils.hasText(userDTO.getPhonenumber()), User::getPhonenumber, userDTO.getPhonenumber());
        wrapper.eq(StringUtils.hasText(userDTO.getStatus()), User::getStatus, userDTO.getStatus());
        Page<User> userPage = new Page<>(pageNum, pageSize);

        page(userPage, wrapper);
        PageVo pageVo = new PageVo(userPage.getRecords(), userPage.getTotal());

        return ResponseResult.okResult(pageVo);
    }

    /**
     * 根据id查询用户信息
     *
     * @param userId
     * @return
     */
    @Override
    public ResponseResult getUserInfo(Long userId) {

        User user = getById(userId);
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, userId);
        List<UserRole> userRoles = userRoleService.list(wrapper);
        List<Long> roleIds = null;
        List<Role> roles = null;
        if (userRoles.size() > 0) {
            roleIds = userRoles.stream()
                    .map(userRole -> userRole.getRoleId())
                    .collect(Collectors.toList());
        }
        if (roleIds.size() > 0) {
            roles = roleService.list();
        }
        UserRoleVo userRoleVo = new UserRoleVo(roleIds, roles, user);
        return ResponseResult.okResult(userRoleVo);
    }

    /**
     * 添加用户
     *
     * @param userDTO
     * @return
     */
    @Override
    @Transactional
    public ResponseResult addUser(UserDTO userDTO) {
        User user = BeanCopyUtils.copyBean(userDTO, User.class);
        //先保存用户得到user_id
        String encode = passwordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        save(user);


        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, user.getId());
        userRoleService.remove(wrapper);
        List<Long> roleIds = userDTO.getRoleIds();
        List<UserRole> userRoles = roleIds.stream()
                .map(ids -> new UserRole(user.getId(), ids))
                .collect(Collectors.toList());
        userRoleService.saveBatch(userRoles);


        return ResponseResult.okResult();
    }

    /**
     * 根据ids删除用户
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional
    public ResponseResult deleteById(List<Long> ids) {
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserRole::getUserId, ids);
        userRoleService.remove(wrapper);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(User::getId, ids);
        remove(queryWrapper);

        return ResponseResult.okResult();
    }

    /**
     * 修改用户
     *
     * @param userDTO
     * @return
     */
    @Override
    @Transactional
    public ResponseResult updateUser(UserDTO userDTO) {
        User user = BeanCopyUtils.copyBean(userDTO, User.class);
        updateById(user);
        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserRole::getUserId, user.getId());
        userRoleService.remove(wrapper);
        List<Long> roleIds = userDTO.getRoleIds();
        List<UserRole> userRoles = roleIds.stream()
                .map(roleId -> new UserRole(user.getId(), roleId))
                .collect(Collectors.toList());
        userRoleService.saveBatch(userRoles);

        return ResponseResult.okResult();
    }
}
